package org.zjt.spring.batch;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.FlatFileItemWriter;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.*;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.transaction.PlatformTransactionManager;


/**
 * @author <a href="juntao.zhang@qq.com">juntao.zhang</a>
 * @Description:
 * @Package org.zjt.spring.batch
 * @date 2018/5/9 11:57
 * @see
 */
public class Main {

    private static final String READ_FILE_PATH = "batch-data-source.csv";

    private static final String WRITE_FILE_PATH = "batch-data-source-output.csv";

    public static void main(String[] args) throws Exception {

        ApplicationContext applicationContext = createBeanApplicationContext();
        // 获取任务启动器
        JobLauncher jobLauncher = applicationContext.getBean(SimpleJobLauncher.class);
        JobRepository jobRepository = applicationContext.getBean(JobRepository.class);
        PlatformTransactionManager transactionManager = applicationContext.getBean(PlatformTransactionManager.class);

        // 创建reader
        FlatFileItemReader<DeviceCommand> flatFileItemReader = new FlatFileItemReader<>();
        flatFileItemReader.setResource(new ClassPathResource(READ_FILE_PATH));
        flatFileItemReader.setLineMapper(new HelloLineMapper());

        // 创建processor
        HelloItemProcessor helloItemProcessor = new HelloItemProcessor();

        // 创建writer
        FlatFileItemWriter<DeviceCommand> flatFileItemWriter = new FlatFileItemWriter<>();
        flatFileItemWriter.setResource(new ClassPathResource(WRITE_FILE_PATH));
        flatFileItemWriter.setLineAggregator(new HelloLineAggregator());


        // 创建Step
        StepBuilderFactory stepBuilderFactory = new StepBuilderFactory(jobRepository, transactionManager);
        Step step = stepBuilderFactory.get("step")
                .<DeviceCommand, DeviceCommand>chunk(1)
                .reader(flatFileItemReader)       // 读操作
                .processor(helloItemProcessor)    // 处理操作
                .writer(flatFileItemWriter)       // 写操作
                .build();

        // 创建Job
        JobBuilderFactory jobBuilderFactory = new JobBuilderFactory(jobRepository);
        Job job = jobBuilderFactory.get("job")
                .start(step)
                .build();

        // 启动任务
        jobLauncher.run(job, new JobParameters());
    }

    /**
     *
     * @return
     */
    public static ApplicationContext creaateXMLApplicationContext() {
        // 加载上下文
        String[] configLocations = {"applicationContext.xml"};
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(configLocations);
        return applicationContext;
    }


    /**
     *
     * @return
     * @throws Exception
     */
    public static ApplicationContext createBeanApplicationContext() throws Exception {
        ConfigurableApplicationContext configurableApplicationContext = new AnnotationConfigApplicationContext();

        ConfigurableListableBeanFactory beanFactory = configurableApplicationContext.getBeanFactory();
        ResourcelessTransactionManager resourcelessTransactionManager = new ResourcelessTransactionManager();
        MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean = new MapJobRepositoryFactoryBean(resourcelessTransactionManager);
        SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
        simpleJobLauncher.setJobRepository(mapJobRepositoryFactoryBean.getObject());
        beanFactory.registerSingleton("resourcelessTransactionManager",resourcelessTransactionManager);
        beanFactory.registerSingleton("mapJobRepositoryFactoryBean",mapJobRepositoryFactoryBean);
        beanFactory.registerSingleton("simpleJobLauncher",simpleJobLauncher);


        beanFactory.initializeBean(simpleJobLauncher,"simpleJobLauncher");
        beanFactory.initializeBean(resourcelessTransactionManager,"resourcelessTransactionManager");
        beanFactory.initializeBean(mapJobRepositoryFactoryBean,"mapJobRepositoryFactoryBean");

        configurableApplicationContext.refresh();
        return configurableApplicationContext;
    }
}
